package com.filesearcher;
import java.awt.BorderLayout;

import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.BufferedInputStream;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.ListModel;

import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import org.jdesktop.layout.GroupLayout;

public class ResultsTab extends JScrollPane {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	private int tabIndexNumber;
	private String tabTitle;
	
	//private JTextArea textArea;
	private JList textArea;
	private String searchText;	
	private String currentMessageText;
	private JProgressBar progressBar;
	private JPanel progressBarPanel;
	private Color messageColor;
	
	private JPopupMenu popupMenu = new JPopupMenu();
	
	private SearchThread relatedThread;
	
	public boolean showLineNumbersSelected;
	public boolean excludeWordsSelected;
	public boolean ignoreCaseSelected;
	
	private GrepSearchUI gui;
	
	private boolean searchInProgress = false;
	
	public ResultsTab(String searchString, SearchThread relatedSearchThread, GrepSearchUI screen)
	{
		/* Set the textarea NOT editable */
		//textArea = new JTextArea();
		gui = screen;
		textArea = new JList();
		textArea.setDoubleBuffered( true );
		textArea.setVisibleRowCount(3);
		// fix small fonts showing
		Font displayFont = new Font("Courier New", Font.PLAIN, 14);
		textArea.setFont(displayFont);
		
		PopupActionListener aListener = new PopupActionListener();
		JMenuItem mi1 = new JMenuItem( "Search within these results" );
		mi1.setActionCommand("1");
		mi1.addActionListener( aListener );
		popupMenu.add(mi1);
		textArea.addMouseListener( new PopupListener() );
		//textArea.setEditable( false );
		//textArea.setEditable(false);
		
		relatedThread = relatedSearchThread;

		this.add( getProgressBarPanel() );
		
		this.setDoubleBuffered( true );
		this.setPreferredSize(new java.awt.Dimension(456, 349));

		searchText = searchString;
	}
	
	public void terminateSearchThread()
	{
		if ( relatedThread.isAlive() )
			relatedThread.stop();
	}
	
	public String getSearchText()
	{
		return searchText;
	}
	
	public String getTabTitle()
	{
		return tabTitle;
	}
	
	public void setTabTitle( String title )
	{
		if ( title != null && title.length() > 0 )
		{
			this.tabTitle = title;
		}
	}
	
	public int getTabIndexNumber()
	{
		return tabIndexNumber;
	}
	
	public void showProgressBar()
	{
		textArea.setVisible( false );
		
		progressBarPanel.setVisible( true );
		progressBar.setIndeterminate( true );
		this.setViewportView( progressBarPanel );		
	}
	
	public void showResultsTextArea()
	{
		progressBarPanel.setVisible( false );
		
		textArea.setVisible( true );
		this.setViewportView( textArea );
	}
	
	public void setText(String text)
	{
		String[] lines = text.split( "\n" );
		textArea.setListData(lines);
		
//		for ( int i=0; i < lines.length; i++ )
//		{
//			if ( Runtime.getRuntime().freeMemory() < 1000000 )
//			{
//				setCurrentMessageText( "OutOfMemoryError : All results will not have been displayed, some maybe be visible." );
//				setMessageColor( Color.RED );
//				break;
//			}
//			else
//			{
//				if ( i > 0 )
//					textArea.append( "\n" + lines[i] );
//				else
//					textArea.append( lines[i] );
//			}
//		}
		
		//textArea.setText( text );
	}
	
	public String getText()
	{
		//return textArea.getText();
		ListModel model = textArea.getModel();
		StringBuffer text = new StringBuffer();
		
		int lines = model.getSize();
		
		for ( int i=0; i<lines; i++)
		{
			if ( i == lines )
				text.append( model.getElementAt( i ) );
			else
				text.append( model.getElementAt( i ) + "\n" );
		}
		
		return text.toString();
	}
	
	public void writeTabResultsToDisk( File tmpFileName )
	{
		ListModel model = textArea.getModel();
	
		int lines = model.getSize();
		
		if ( tmpFileName != null && tmpFileName.exists() )
    	{
    		try 
    		{
    			FileWriter fileWriter = new FileWriter( tmpFileName );
    			BufferedWriter out = new BufferedWriter( fileWriter );
    			
    			for ( int i=0; i<lines; i++)
    			{
    				if ( i > 0 )
    					out.write( "\n" + model.getElementAt( i ) );
    				else
    					out.write( model.getElementAt( i ).toString() );
    			}				
    			
    			out.close();
    		} 
    		catch (IOException e) 
    		{
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
	}
	
	public void readTabResultsFromDisk( File tmpFile )
	{
		ArrayList lines = new ArrayList();
		
		if ( tmpFile != null )
    	{
			FileInputStream fis = null;
		    BufferedInputStream bis = null;
		    DataInputStream dis = null;

		    try {
		      fis = new FileInputStream( tmpFile );

		      // Here BufferedInputStream is added for fast reading.
		      bis = new BufferedInputStream(fis);
		      dis = new DataInputStream(bis);

		      // dis.available() returns 0 if the file does not have more lines.
		      while (dis.available() != 0) {

		      // this statement reads the line from the file and print it to
		        // the console.
		        lines.add( dis.readLine() );
		      }

		      // dispose all the resources after using them.
		      fis.close();
		      bis.close();
		      dis.close();

		    } catch (FileNotFoundException e) {
		      e.printStackTrace();
		    } catch (IOException e) {
		      e.printStackTrace();
		    }
		}
    	
		textArea.setListData( lines.toArray() );
	}
	
	public void setMessageColor(Color textColor)
	{
		messageColor = textColor;
	}
	
	public Color getMessageColor()
	{
		return messageColor;
	}
	
	public void setCurrentMessageText(String message)
	{
		currentMessageText = message;
	}
	
	public String getCurrentMessageText()
	{
		return currentMessageText;
	}
	
	public void clearText()
	{
		this.remove( textArea );
		textArea.removeAll();
		//textArea.setText(null);
		Runtime.getRuntime().gc();
	}
	
	public void setTabIndexNumber( int tabNum )
	{
		tabIndexNumber = tabNum;
	}
	
	public void setSearchInProgress( boolean value )
	{
		if ( value )
		{
			searchInProgress = true;
			setTabTitle( "* " + getTabTitle() );
		}
		else
		{
			searchInProgress = false;
			setTabTitle( getTabTitle().substring( 2 ) );
		}
	}
	
	public boolean getSearchInProgress()
	{
		return searchInProgress;
	}
	
	private JPanel getProgressBarPanel() {
		if(progressBarPanel == null) {
			progressBarPanel = new JPanel();
			GroupLayout progressBarPanelLayout = new GroupLayout((JComponent)progressBarPanel);
			progressBarPanel.setLayout(progressBarPanelLayout);
			progressBarPanel.setPreferredSize(new java.awt.Dimension(278, 198));
			{
				progressBar = new JProgressBar();
				BorderLayout progressBarLayout = new BorderLayout();
				progressBar.setLayout(progressBarLayout);
			}
			progressBarPanelLayout.setHorizontalGroup(progressBarPanelLayout.createSequentialGroup()
				.addContainerGap()
				.add(progressBar, 0, 254, Short.MAX_VALUE)
				.addContainerGap());
			progressBarPanelLayout.setVerticalGroup(progressBarPanelLayout.createSequentialGroup()
				.addContainerGap()
				.add(progressBar, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE)
				.addContainerGap(164, 164));
		}
		return progressBarPanel;
	}
	
	class PopupListener extends MouseAdapter 
	{
	    public void mousePressed(MouseEvent e) 
	    {
	      showPopup(e);
	    }
	    public void mouseReleased(MouseEvent e) 
	    {
	      showPopup(e);
	    }
	    private void showPopup(MouseEvent e) 
	    {
	      if (e.isPopupTrigger()) 
	      {
	        popupMenu.show(e.getComponent(), e.getX(), e.getY());
	      }
	    }
	}
	
	class PopupActionListener implements ActionListener
    {

		public void actionPerformed(ActionEvent e) 
		{
			String actionCommand = e.getActionCommand();
			
			if ( actionCommand.equals( "1") )
			{
				fireNewSearch();
			}			
		}
    }
	
	private void fireNewSearch()
	{
		File tmpFile = GrepSearchUI.getTabTempFileName( this );
		
		if ( tmpFile != null )
		{
			SearchThread sThread = new SearchThread( "Poo", tmpFile, false, null, false, 10, false, false, gui);
			sThread.start();
		}
		
	}
}
